package com.ipDev.moyvSys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ipDev.moyvSys.constant.StatusConstant;
import com.ipDev.moyvSys.domain.dto.BookDTO;
import com.ipDev.moyvSys.domain.po.Book;
import com.ipDev.moyvSys.domain.po.Section;
import com.ipDev.moyvSys.domain.vo.BookVO;
import com.ipDev.moyvSys.mapper.BookMapper;
import com.ipDev.moyvSys.service.IBookService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ipDev.moyvSys.service.ISectionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author fish
 * @since 2024-10-26
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements IBookService {

    private final ISectionService sectionService;


    @Override
    @Transactional
    public void saveOne(BookDTO bookDTO) {
        if (BeanUtil.isEmpty(bookDTO)) {
            log.error("请求参数为空!");
        }
        Book book = new Book();
        BeanUtil.copyProperties(bookDTO, book);
        save(book);
        if (!CollUtil.isEmpty(bookDTO.getSectionList())) {
            //上面的书本完成保存之后 将bookId拿过来用
            List<Section> sectionList = bookDTO.getSectionList();
            for (Section section : sectionList) {
                section.setBookId(book.getId());
            }
            sectionService.saveBatch(sectionList);
        }
    }

    @Override
    public List<BookVO> listEnableBook() {
        //尽量减少对数据库的多次访问 减轻访问压力
        List<Book> list = lambdaQuery().eq(Book::getStatus, StatusConstant.ENABLE).list();
        return generateBookVOList(list);
    }


    @Override
    public List<BookVO> listAllBook() {
        List<Book> list = lambdaQuery().list();
        return generateBookVOList(list);
    }

    @Override
    @Transactional
    public void delByBookId(Integer id) {
        Book book = lambdaQuery().eq(Book::getId, id).one();
        if (book == null) {
            log.error("书籍不存在");
            return;
        }
        QueryWrapper<Section> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", book.getId());
        sectionService
                .remove(queryWrapper);
    }

    @Override
    @Transactional
    public void delByBookIds(List<Integer> bookIds) {
        if (CollUtil.isEmpty(bookIds)) {
            log.info("传入的bookIds为空!");
            return;
        }
        List<Book> bookList = lambdaQuery().in(Book::getId, bookIds).list();
        if (CollUtil.isEmpty(bookList)) {
            log.error("不存在符合条件的书籍!");
            return;
        }
        //只能删除状态为未启用的书籍
        for (Book book : bookList) {
            if (book.getStatus().equals(StatusConstant.ENABLE)) {
                log.error("不能删除已启用的书籍!");
                return;
            }
        }
        removeBatchByIds(bookIds);
        sectionService.remove(sectionService.lambdaQuery().in(Section::getBookId, bookIds));
    }

    @Override
    public List<BookVO> search(BookDTO dto) {
        if (dto == null) {
            log.error("请求参数不能为空!");
            return Collections.emptyList();
        }
        List<Book> bookList = lambdaQuery().like(dto.getName() != null, Book::getName, dto.getName())
                .eq(dto.getCategoryId() != null, Book::getCategoryId, dto.getCategoryId())
                .eq(dto.getYear() != null, Book::getYear, dto.getYear())
                .eq(dto.getStatus() != null, Book::getStatus, dto.getStatus()).list();
        return generateBookVOList(bookList);
    }

    @Override
    @Transactional
    public void updateBook(BookDTO bookDTO) {
        if (bookDTO == null) {
            log.error("请求参数不能为空!");
            return;
        }
        Book book = new Book();
        BeanUtil.copyProperties(bookDTO, book);
        updateById(book);
        //更新章节相关信息
        //只更新带有章节id的
        if (!CollUtil.isEmpty(bookDTO.getSectionList())) {
            List<Section> sectionList = bookDTO.getSectionList();
            List<Section> filterList = sectionList.stream()
                    .filter(section -> section.getId() != null)
                    .collect(Collectors.toList());
            sectionService.updateBatchById(filterList);
        }
    }

    public List<BookVO> generateBookVOList(List<Book> list) {
        //尽量减少对数据库的多次访问 减轻访问压力
        List<Integer> bookIdList = list.stream().map(Book::getId).collect(Collectors.toList());
        //一次全部查出来
        List<Section> sectionList = sectionService.lambdaQuery().in(Section::getBookId, bookIdList).list();
        //改造成map方便取用
        Map<Integer, List<Section>> map = sectionList.stream().collect(Collectors.groupingBy(Section::getBookId));

        List<BookVO> voList = new ArrayList<>();
        for (Book book : list) {
            BookVO vo = new BookVO();
            BeanUtil.copyProperties(book, vo);
            vo.setSectionList(map.get(book.getId()));
            voList.add(vo);
        }
        return voList;
    }
}
